package com.cm.etax;

import com.cm.etax.exceptions.EtaxException;
import com.cm.etax.exceptions.RetryWarning;
import com.cm.etax.sms.exceptions.SmsException;
import com.cm.kits.DateTimeKits;
import com.cm.rpa.RpaCore;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.NoSuchElementException;

import java.time.temporal.ChronoUnit;

/**
 * 方法基础类
 *
 * @author LWang 2023.01.29
 * @since 1.0.0
 */
@Slf4j
public abstract class BaseFunction {

    private final BaseEtax etax;
    private final EtaxConfig config;
    private final RpaCore rpa;

    protected static final int SLEEP_TIME = 3;
    protected static final long WAIT_TIME = 10;
    protected static final long MOUSE_OFFSET = 50;

    protected BaseEtax etax() {
        return this.etax;
    }

    protected EtaxConfig config() {
        return this.config;
    }

    protected RpaCore rpa() {
        return this.rpa;
    }

    public BaseFunction(BaseEtax etax) {
        this.etax = etax;
        this.config = etax.config();
        this.rpa = etax.rpa();
    }

    /**
     * 统一异常处理
     *
     * @param cause         要处理的异常
     * @param messagePrefix 消息前缀
     * @return 异常消息描述
     */
    protected <T> FunctionResult<T> handleException(Throwable cause, String messagePrefix) {
        // 1. 处理需要单独处理的异常
        if (cause instanceof NoSuchElementException e) {
            return new FunctionResult<>(false, messagePrefix + e.getMessage(), null);
        } else if (cause instanceof EtaxException e) {
            return new FunctionResult<>(false, messagePrefix + e.getMessage(), null);
        } else if (cause instanceof SmsException e) {
            switch (e.getFlag()) {
                case SmsException.PHONE_LOCK -> throw new RetryWarning(5, e.getMessage());
                case SmsException.PHONE_LIMIT_RANGE -> throw new RetryWarning(15, e.getMessage());
                case SmsException.PHONE_FULL_DAY ->
                        throw new RetryWarning(Math.abs(DateTimeKits.timeRemaining(ChronoUnit.MINUTES)), e.getMessage());

            }
        } else if (cause instanceof RetryWarning e) {
            throw e;
        }
        // 2. 其他异常使用 messagePrefix 包裹后，返回失败执行结果
        log.error("发生未知的异常，", cause);
        return new FunctionResult<>(false, messagePrefix + "发生未知异常！", null);
    }
}
